package com.nida;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.nida.loader.Configurator;
import com.nida.loader.NidaConfig;
import com.nida.mvc.RequestMethod;
import com.nida.route.IntercepterHandler;
import com.nida.route.IntercepterType;
import com.nida.route.RouteHandler;
import com.nida.route.Routers;

import blade.kit.Assert;
import blade.kit.config.Config;
import blade.kit.config.loader.ConfigLoader;
import cn.sunline.rest.NidaServer;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;

public class Nida {

    private boolean isInit = false;
    
    private NidaConfig nidaConfig = null;
    
    private Routers routers = null;
    
    private int port = Const.DEFAULT_PORT;
    
    private NidaServer nidaServer = null;

    private String contextPath = "/";
    
    private Nida(){
        this.nidaConfig = new NidaConfig();
        this.routers = new Routers();
    }
    
    static final class NidaHolder{
        private static final Nida ME = new Nida();
    }
    
    public static Nida me(){
        return NidaHolder.ME;
    }
    
    public void init(){
        if (!isInit) {
            isInit = true;
        }
        
    }
    
    public Routers getRouters(){
        return this.routers;
    }
    
    /**
     * @Description 添加配置文件
     */
    public void addConfigFile(String fileName){
        Assert.notBlank(fileName);
        Config config = ConfigLoader.load(fileName);
        Configurator.init(this.nidaConfig,config);
    }
    
    
    
    /* ============以下为 Route 操作的方法====================*/
    
    /**
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param pack
     * @return
     */
    public Nida addRoutePack(String pack){
        return this.addRoutePacks(pack);
    }
    
    /**
     * @Description (TODO这里用一句话描述这个方法的作用)
     * @param packs
     * @return
     */
    public Nida addRoutePacks(String ...packs){
        Assert.notNull(packs);
        this.nidaConfig.addRoutePackages(packs);
        return this;
    }
    
    public Set<String> getRoutePacks(){
        return this.nidaConfig.getRoutePackages();
    }
    
    /**
     * @Description 添加get请求路由
     * @return
     */
    public Nida get(String path,RouteHandler handler){
        routers.addRoute(path,handler,RequestMethod.GET);
        return this;
    }
    
    public Nida post(String path,RouteHandler handler){
        routers.addRoute(path,handler,RequestMethod.POST);
        return this;
    }
    
    public Nida delete(String path,RouteHandler handler){
        routers.addRoute(path,handler,RequestMethod.DELETE);
        return this;
    }
    
    public Nida update(String path,RouteHandler handler){
        routers.addRoute(path,handler,RequestMethod.UPDATA);
        return this;
    }
    
    public Nida all(String path,RouteHandler handler){
        routers.addRoute(path,handler,RequestMethod.ALL);
        return this;
    }
    
    public Nida beforeInterceptor(String path,IntercepterHandler handler){
        routers.addIntercepter(path,handler,IntercepterType.BEFORE);
        return this;
    }
    
    public Nida afterInterceptor(String path,IntercepterHandler handler){
        routers.addIntercepter(path,handler,IntercepterType.AFTER);
        return this;
    }
    
    /* ============== port ============ */
    
    public Nida port(int port) {
        this.port = port;
        return this;
    }
    
    /* ============== server start and stop ======== */
    
    public void start( String contextPath) {
        try {
            Assert.notBlank(contextPath);
            this.contextPath  = contextPath;
            //启动前初始化所有的配置
            init();
            nidaServer = new NidaServer(this.port);
            nidaServer.run();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    public void start(){
        this.start("/");
    }
    
    public void stop(){
        //TODO 暂时停止服务功能不起作用
        nidaServer.stop();
    }
    
    
    public String getContextPath() {
        return contextPath;
    }
    
    public static void main(String[] args) {
        Nida nida = Nida.me();
        nida.get("/", new RouteHandler() {
            @Override
            public void handle(FullHttpRequest request, FullHttpResponse response) {
                Map<String, String> obj = new HashMap<>();
                obj.put("name", "zhangli");
                rendJson(obj);
            }
        });
        nida.start("/a");
    }
    
    
}
